/*
	The game of life
	----------------
	The game of life takes place on a grid of cells. Each cell can be either
	alive or dead. These cells change over generations according to the 
	following rules:
		
		* If more than 3 cells or less than two cells surround a living cell, 
		  it dies
		* If there are exactly 2 cells surrounding a dead cell, it gets (re)born
*/

#include <iostream>

using namespace std;

void showgrid(bool grid[10][10]){
	for (int i=0; i<10; i++){
		for (int j=0; j<10; j++){
			if (grid[i][j]){
				cout << "X ";
			}else{
				cout << ". ";
			}
		}
		cout << endl;		
	}
}

void calculate(bool grid[10][10]){
	/*  We need to make a copy of the grid first */
	int i, j, k, l, count;
	bool grid_copy[12][12]; // the copy needs to be padded with zeroes around
							// the grid so life can't expand infinitely
							
	for (i=0; i<12; i++){  // zero the copy first
		for (int j=0; j<12; j++){
			grid_copy[i][j] = 0;
		}
	}						
	
	for (i=1; i<11; i++){ //then populate the inner grid
		for (int j=1; j<11; j++){ 
			grid_copy[i][j] = grid[i-1][j-1]; // subtract 1 for the padding at the left and top
		}
	}
	
	/* 	now use the copy grid to calculate the next generation and update the
		original grid. since arrays are passed by reference, I can chance its
		contents directly	*/
		
	for (i=1; i<11; i++){
		for (int j=1; j<11; j++){ //move through each cell except the padding
			count=0;
			for (k=-1; k<2; k++){
				for (l=-1; l<2; l++){
					if (!(k==0 && l==0) && grid_copy[i+k][j+l]) count++;  //count the surrounding cells [3x3]
				}
			}
			if (count==3) grid[i-1][j-1] = 1; // conditions for new life
			if (count>3 || count<2) grid[i-1][j-1] = 0; // conditions for death			
		}
	}
	
}

int main(){
	bool lifegrid[10][10] = {	{0,0,1,0,0,0,0,0,0,0},
								{0,0,0,1,0,0,0,0,0,0},
								{0,1,1,1,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0},
								{0,0,0,0,0,0,0,0,0,0}	};
								
	for (int i=0; i<20; i++){ // show 10 generations
		cout << "Generation " << i << endl;
		showgrid(lifegrid);	
		calculate(lifegrid);
	}
		
	return 0;
}
